package org.nativejpa.mapping;

import java.util.Map;
import java.util.HashMap;
import java.util.Collection;

/**
 * Repository to hold all mapping metadata
 *
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 * @create 2009-3-12 16:09:30
 */
public class EntityRepository {

    /**
     * repostiory holds all entity metadata
     */
    protected static Map<Class<?>, EntityMetadata> entityMetadatas = new HashMap<Class<?>, EntityMetadata>();

    private static final EntityRepository instance = new EntityRepository();

    private EntityRepository() {
    }

    public static EntityRepository getInstance(){
        return instance;
    }

    public void parseEntities(Class<?>[] entityClasses) {
        for(Class<?> entityClass : entityClasses){
            parseEntityClass(entityClass);
        }
    }

    public EntityMetadata getEntityMetadata(Class<?> entityClass) {
        // try introspec entityclass if first time
        parseEntityClass(entityClass);
        return entityMetadatas.get(entityClass);
    }

    // get all column metadata, include JOIN
    public Collection<ColumnMetadata> getAllColumnMetadatas(Class<?> entityClass) {
        return getEntityMetadata(entityClass).getColumnMetadatas();
    }

    public Collection<JoinColumnMetadata> getJoinColumnEntries(Class<?> resultClass) {
        return getEntityMetadata(resultClass).getJoinColumnMetadatas();
    }

    public Collection<ColumnMetadata> getNormalColumnMetadatas(Class<?> resultClass) {
        return getEntityMetadata(resultClass).getNormalColumnMetadatas();
    }

    public ColumnMetadata getColumnMetadata(Class<?> resultClass, String columnName) {
        return getEntityMetadata(resultClass).getColumnMetadata(columnName);
    }

    public boolean isColumnExisted(Class<?> entityClass, String columnName){
        return getEntityMetadata(entityClass).isColumnExisted(columnName);
    }

    public ColumnMetadata getPKColumnMetadata(Class<?> resultClass){
        return getEntityMetadata(resultClass).getPKColumnMetadata();
    }

    public ColumnMetadata getVersionColumnMetadata(Class<?> resultClass){
        return getEntityMetadata(resultClass).getVersionColumnMetadata();
    }

    /**
     * if entityClass not exist in repo, new one
     * @param entityClass
     */
    private synchronized void parseEntityClass(Class<?> entityClass){
        if(!entityMetadatas.containsKey(entityClass)) {
            // init EntityMetadata if not exist
            entityMetadatas.put(entityClass, new EntityMetadata(entityClass));
        }
    }
}
